Prepare data

Read and format data


df_ger_covid <- read_csv('Germany_timeseries_prep.csv')
df_ger_socdist <- read_csv('Germany_socdist_fb_kreis.csv')
df_ger_ctrl <- read.csv2('Germany_controls.csv', sep = ';', dec=',')

# prevalence 
df_ger_covid <- df_ger_covid %>% mutate(date = as.Date(date, "%d%b%Y"),
                                  kreis = as.character(kreis)) %>% 
  dplyr::select(-runday, -kreis_name, -ewz, -shape__area, 
                -cumcase, -anzahlfall, -popdens) %>%
  dplyr::rename(pers_o = open, 
         pers_c = sci,
         pers_e = extra,
         pers_a = agree,
         pers_n = neuro)

df_ger_covid

# social distancing
df_ger_socdist <- df_ger_socdist %>% 
  rename(socdist_single_tile = all_day_ratio_single_tile_users) %>%
  select(kreis, date, socdist_single_tile) %>% 
  mutate(kreis = as.character(kreis))

df_ger_socdist
NA
# controls 
df_ger_ctrl <- df_ger_ctrl %>% select(-kreis_nme) %>%
    mutate(kreis = as.character(kreis),
           popdens = popdens %>% 
             as.character() %>%
             str_replace('\\.', '')%>%
             as.numeric())

df_ger_ctrl
NA
NA

Explore data

Plot prevalence over time


df_ger %>% ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall prevalence over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_ger %>% mutate(prev_tail = cut(.[[i]], 
      breaks = c(-Inf, quantile(.[[i]], 0.2), quantile(.[[i]], 0.8), Inf),
      labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(prev_tail != 'center') %>%
  ggplot(aes(x=time, y=rate_day)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~prev_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Plot social distancing (single tile) over time


df_ger %>% ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_ger %>% mutate(prev_tail = cut(.[[i]], 
      breaks = c(-Inf, quantile(.[[i]], 0.2), quantile(.[[i]], 0.8), Inf),
      labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(prev_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~prev_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}

Control for weekend effect


df_ger_loess <- df_ger %>% 
  mutate(weekday = format(date, '%u')) %>% 
  filter(!weekday %in% c('6','7')) %>% 
  split(.$kreis) %>%
  map(~ loess(socdist_single_tile ~ time, data = .)) %>%
  map(predict, 1:max(df_ger$time)) %>% 
  bind_rows() %>% 
  gather(key = 'kreis', value = 'loess') %>% 
  group_by(kreis) %>% 
  mutate(time = row_number())

df_ger_loess

df_ger <- df_ger %>% merge(df_ger_loess, by=c('kreis', 'time')) %>% 
  mutate(weekday = format(date, '%u')) %>% 
  mutate(socdist_single_tile_clean = ifelse(weekday %in% c('6','7'), loess,
                                            socdist_single_tile)) %>%
  arrange(kreis, time) %>% 
  select(-weekday)

df_ger %>% drop_na()
NA

df_ger %>% ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  theme(legend.position="none") +
  ggtitle("Overall social distancing (single tile) over time")


pers <- c('pers_o', 'pers_c', 'pers_e', 'pers_a', 'pers_n')

for (i in pers){

gg <- df_ger %>% mutate(prev_tail = cut(.[[i]], 
      breaks = c(-Inf, quantile(.[[i]], 0.2), quantile(.[[i]], 0.8), Inf),
      labels = c('lower tail', 'center', 'upper tail'))) %>% 
  filter(prev_tail != 'center') %>%
  ggplot(aes(x=time, y=socdist_single_tile_clean)) + 
  geom_point(aes(col=kreis, size=popdens)) + 
  geom_smooth(method="loess", se=T) + 
  facet_wrap(~prev_tail) + 
  theme(legend.position="none") +
  ggtitle(i)

print(gg)
}


df_ger <- df_ger %>% mutate(socdist_single_tile = socdist_single_tile_clean) %>% 
  select(-loess, -socdist_single_tile_clean)

Correlations


df_ger %>% group_by(kreis) %>% 
  summarize_if(is.numeric, mean) %>% 
  select(-kreis, -time) %>% 
  cor(use='pairwise.complete') %>% 
  round(3)
                    pers_e pers_a pers_c pers_n pers_o rate_day socdist_single_tile  women academics    cdu    afd
pers_e               1.000  0.223  0.255 -0.375  0.277    0.164               0.151 -0.050     0.196  0.090 -0.152
pers_a               0.223  1.000  0.347 -0.379  0.167    0.136              -0.014  0.037     0.233  0.024  0.008
pers_c               0.255  0.347  1.000 -0.373 -0.063   -0.004               0.019 -0.002     0.027 -0.017  0.132
pers_n              -0.375 -0.379 -0.373  1.000 -0.046   -0.101              -0.136  0.053    -0.147 -0.032  0.113
pers_o               0.277  0.167 -0.063 -0.046  1.000    0.117               0.077  0.195     0.501 -0.151 -0.213
rate_day             0.164  0.136 -0.004 -0.101  0.117    1.000               0.261 -0.127     0.063  0.390 -0.182
socdist_single_tile  0.151 -0.014  0.019 -0.136  0.077    0.261               1.000 -0.053    -0.026  0.293 -0.434
women               -0.050  0.037 -0.002  0.053  0.195   -0.127              -0.053  1.000     0.335 -0.404 -0.107
academics            0.196  0.233  0.027 -0.147  0.501    0.063              -0.026  0.335     1.000 -0.407 -0.177
cdu                  0.090  0.024 -0.017 -0.032 -0.151    0.390               0.293 -0.404    -0.407  1.000 -0.341
afd                 -0.152  0.008  0.132  0.113 -0.213   -0.182              -0.434 -0.107    -0.177 -0.341  1.000
hospital_beds       -0.037  0.004 -0.157  0.111  0.281   -0.055              -0.257  0.456     0.383 -0.309  0.011
tourism_beds        -0.131 -0.104 -0.053  0.034 -0.099   -0.076               0.002  0.003    -0.167  0.210 -0.044
gdp                  0.141  0.044 -0.052 -0.117  0.343    0.150              -0.015  0.060     0.534 -0.093 -0.223
manufact            -0.042 -0.040 -0.042  0.003 -0.073    0.196              -0.100 -0.313    -0.145  0.229  0.120
airport             -0.188 -0.167 -0.112  0.171 -0.222    0.022              -0.130 -0.208    -0.416  0.277  0.190
age                 -0.289 -0.080  0.125  0.178 -0.368   -0.301              -0.242  0.149    -0.492 -0.167  0.583
popdens              0.127 -0.025 -0.084 -0.007  0.415   -0.044              -0.002  0.350     0.620 -0.473 -0.211
                    hospital_beds tourism_beds    gdp manufact airport    age popdens
pers_e                     -0.037       -0.131  0.141   -0.042  -0.188 -0.289   0.127
pers_a                      0.004       -0.104  0.044   -0.040  -0.167 -0.080  -0.025
pers_c                     -0.157       -0.053 -0.052   -0.042  -0.112  0.125  -0.084
pers_n                      0.111        0.034 -0.117    0.003   0.171  0.178  -0.007
pers_o                      0.281       -0.099  0.343   -0.073  -0.222 -0.368   0.415
rate_day                   -0.055       -0.076  0.150    0.196   0.022 -0.301  -0.044
socdist_single_tile        -0.257        0.002 -0.015   -0.100  -0.130 -0.242  -0.002
women                       0.456        0.003  0.060   -0.313  -0.208  0.149   0.350
academics                   0.383       -0.167  0.534   -0.145  -0.416 -0.492   0.620
cdu                        -0.309        0.210 -0.093    0.229   0.277 -0.167  -0.473
afd                         0.011       -0.044 -0.223    0.120   0.190  0.583  -0.211
hospital_beds               1.000       -0.039  0.400    0.022  -0.046 -0.107   0.390
tourism_beds               -0.039        1.000 -0.113   -0.102   0.357  0.198  -0.225
gdp                         0.400       -0.113  1.000    0.546  -0.165 -0.483   0.474
manufact                    0.022       -0.102  0.546    1.000   0.169 -0.063  -0.137
airport                    -0.046        0.357 -0.165    0.169   1.000  0.316  -0.438
age                        -0.107        0.198 -0.483   -0.063   0.316  1.000  -0.461
popdens                     0.390       -0.225  0.474   -0.137  -0.438 -0.461   1.000
 

Modelling

Prepare functions


# function calculates all relevant models
run_models <- function(y, lvl1_x, lvl2_x, lvl2_id, data, ctrls=F){

  # subset data
  data = data %>% 
    dplyr::select(all_of(y), all_of(lvl1_x), all_of(lvl2_x), all_of(lvl2_id), 
                  popdens, rate_day)
  data = data %>% 
    dplyr::rename(y = all_of(y),
           lvl1_x = all_of(lvl1_x),
           lvl2_x = all_of(lvl2_x),
           lvl2_id = all_of(lvl2_id)
           )
  
  # configure optimization procedure
  ctrl_config <- lmeControl(opt = 'optim', maxIter = 100, msMaxIter = 100)

  # baseline
  baseline <- lme(fixed = y ~ 1, random = ~ 1 | lvl2_id, 
                    data = data,
                    correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept fixed slope
  random_intercept <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                          random = ~ 1 | lvl2_id,
                            data = data,
                            correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # random intercept random slope
  random_slope <- lme(fixed = y ~ lvl1_x + lvl2_x, 
                      random = ~ lvl1_x | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction <- lme(fixed = y ~ lvl1_x * lvl2_x, 
                     random = ~ lvl1_x | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction)
  
  
  if (ctrls == 'dem' | ctrls == 'prev'){
    
    # random intercept random slope
    random_slope_ctrl_dem <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens,
                              random = ~ lvl1_x | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_main_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
    # cross level interaction
    interaction_ctrl_int_dem <- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')        
    
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem)
  }
  
  if (ctrls == 'prev'){
  
    # random intercept random slope
    random_slope_ctrl_prev <- lme(fixed = y ~ lvl1_x + lvl2_x + popdens + rate_day,
                              random = ~ lvl1_x + rate_day | lvl2_id, 
                          data = data,
                          correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')  
    
        # cross level interaction
    interaction_ctrl_main_prev <- lme(fixed = y ~ lvl1_x * lvl2_x + popdens + rate_day,
                             random = ~ lvl1_x | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                    control = ctrl_config,
                  method = 'ML')
  
  
    # cross level interaction
    interaction_ctrl_int_prev<- lme(fixed = y ~ lvl1_x * lvl2_x + lvl1_x * popdens + rate_day,
                             random = ~ lvl1_x + rate_day | lvl2_id, 
                         data = data,
                         correlation = corAR1(),
                          control = ctrl_config,
                  method = 'ML')
  
    # create list with results
    results <- list('baseline' = baseline, 
                    "random_intercept" = random_intercept, 
                    "random_slope" = random_slope,
                    "interaction" = interaction,
                    "random_slope_ctrl_dem" = random_slope_ctrl_dem,
                    "interaction_ctrl_main_dem" = interaction_ctrl_main_dem,
                    "interaction_ctrl_int_dem" = interaction_ctrl_int_dem,                    
                    "random_slope_ctrl_prev" = random_slope_ctrl_prev,
                    "interaction_ctrl_main_prev" = interaction_ctrl_main_prev,
                    "interaction_ctrl_int_prev" = interaction_ctrl_int_prev)
  }
  
  if(ctrls == 'exp'){
    # random intercept random slope
  random_slope_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) + lvl2_x, 
                      random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                        data = data,
                        correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')

  # cross level interaction
  interaction_exp <- lme(fixed = y ~ (lvl1_x + I(lvl1_x^2)) * lvl2_x, 
                     random = ~ (lvl1_x + I(lvl1_x^2)) | lvl2_id, 
                       data = data,
                       correlation = corAR1(),
                  control = ctrl_config,
                  method = 'ML')  
  
  
  # create list with results
  results <- list('baseline' = baseline, 
                  "random_intercept" = random_intercept, 
                  "random_slope" = random_slope,
                  "interaction" = interaction,                  
                  "random_slope_exp" = random_slope_exp,
                  "interaction_exp" = interaction_exp)
  }
  
  return(results)
        
}

# extracts table with coefficients and tests statistics
extract_results <- function(models) {
  
  models_summary <- models %>% 
  map(summary) %>% 
  map("tTable") %>% 
  map(as.data.frame) %>% 
  map(round, 10) 
  # %>% map(~ .[str_detect(rownames(.), 'Inter|lvl'),])
  
  return(models_summary)
  
}


compare_models <- function(models) {

  mdl_names <- models %>% names()
  
  str = ''
  for (i in mdl_names){
    
    mdl_str <- paste('models$', i, sep = '')
    
    if(i == 'baseline'){
      str <- mdl_str
    }else{
    str <- paste(str, mdl_str, sep=', ')
    }
  }
  
  anova_str <- paste0('anova(', str, ')')
  mdl_comp <- eval(parse(text=anova_str))
  rownames(mdl_comp) = mdl_names
  return(mdl_comp)
}

Rescale Data


lvl2_scaled <- df_ger %>% 
  dplyr::select(-time, -rate_day, -socdist_single_tile, -date) %>% 
  distinct() %>% 
  mutate_at(vars(-kreis), scale)
  
lvl1_scaled <- df_ger %>% select(kreis, time, rate_day, socdist_single_tile) %>% 
  mutate_at(vars(-kreis, -time), scale)

df_ger_scaled <- plyr::join(lvl1_scaled, lvl2_scaled, by = 'kreis')

head(df_ger_scaled)
NA
NA

Predict prevalence

prevalence ~ openness


models_o_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_o', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'dem')

extract_results(models_o_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_o_covid)
NA

prevalence ~ conscientiousness


models_c_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'dem')

extract_results(models_c_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_c_covid)
NA
NA

prevalence ~ extraversion


models_e_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'dem')

extract_results(models_e_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_e_covid)
NA
NA

prevalence ~ agreeableness


models_a_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'dem')

extract_results(models_a_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_a_covid)
NA
NA

prevalence ~ neuroticism


models_n_covid <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'dem')

extract_results(models_n_covid)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem
compare_models(models_n_covid)
NA
NA

Predict social distancing

social distancing ~ openness


models_o_socdist <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_o', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'prev')

extract_results(models_o_socdist)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_o_socdist)
NA

social distancing ~ conscientiousness


models_c_socdist <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'prev')

extract_results(models_c_socdist)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_c_socdist)
NA
NA
NA

social distancing ~ extraversion


models_e_socdist <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'prev')

extract_results(models_e_socdist)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_e_socdist)
NA
NA
NA

social distancing ~ agreeableness


models_a_socdist <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'prev')

extract_results(models_a_socdist)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_a_socdist)
NA
NA
NA

social distancing ~ neuroticism


models_n_socdist <-run_models(y = 'socdist_single_tile', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'prev')

extract_results(models_n_socdist)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_ctrl_dem

$interaction_ctrl_main_dem

$interaction_ctrl_int_dem

$random_slope_ctrl_prev

$interaction_ctrl_main_prev

$interaction_ctrl_int_prev
compare_models(models_n_socdist)
NA
NA

prevalence ~ conscientiousness


models_c_covid_exp <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_c', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'exp')

extract_results(models_c_covid_exp)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_exp

$interaction_exp
compare_models(models_c_covid_exp)
NA

prevalence ~ extraversion


models_e_covid_exp <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_e', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'exp')

extract_results(models_e_covid_exp)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_exp

$interaction_exp
compare_models(models_e_covid_exp)
NA

prevalence ~ agreeableness


models_a_covid_exp <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_a', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'exp')

extract_results(models_a_covid_exp)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_exp

$interaction_exp
compare_models(models_a_covid_exp)
NA

prevalence ~ neuroticism


models_n_covid_exp <-run_models(y = 'rate_day', 
                         lvl1_x = 'time', 
                         lvl2_x = 'pers_n', 
                         lvl2_id = 'kreis', 
                         data = df_ger_scaled,
                         ctrls = 'exp')

extract_results(models_n_covid_exp)
$baseline

$random_intercept

$random_slope

$interaction

$random_slope_exp

$interaction_exp
compare_models(models_n_covid_exp)
NA

Create overview table

Define function to create overview tables


summary_table <- function(models, dv_name, prev=F){

  temp_df_ctrl_main <- NULL
  temp_df_ctrl_int <- NULL
  temp_df_ctrl_int_prev <- NULL
  
  for (i in models){
    results <- i %>% extract_results()
    
    results_ctrl_main <- results$interaction_ctrl_main_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_main <- temp_df_ctrl_main %>% rbind(results_ctrl_main)
    
    results_ctrl_int <- results$interaction_ctrl_int_dem['lvl1_x:lvl2_x',]
    temp_df_ctrl_int <- temp_df_ctrl_int %>% rbind(results_ctrl_int)
    
    if(prev){
      results_ctrl_int_prev <- results$interaction_ctrl_int_prev['lvl1_x:lvl2_x',]
      temp_df_ctrl_int_prev <- temp_df_ctrl_int_prev %>% rbind(results_ctrl_int_prev)
    }
        
  }
  
  names_ctrl_main <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens')
  rownames(temp_df_ctrl_main) <- names_ctrl_main

  names_ctrl_int <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time')
  rownames(temp_df_ctrl_int) <- names_ctrl_int

  if(prev){
    names_ctrl_int_prev <- paste0(dv_name, '~', c('o', 'c', 'e', 'a', 'n'), '*time', '_crtl_popdens*time_prev')
    rownames(temp_df_ctrl_int_prev) <- names_ctrl_int_prev
    
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int, temp_df_ctrl_int_prev) %>% round(4)
  }else{
    sum_tab <- rbind(temp_df_ctrl_main, temp_df_ctrl_int) %>% round(4)
  }


  
  return(sum_tab)

} 

Create overview tables

# prevalence
models_prev <- list(models_o_covid, 
                    models_c_covid, 
                    models_e_covid, 
                    models_a_covid, 
                    models_n_covid)

sum_tab_prev <- summary_table(models_prev, dv_name = 'prev')

write.table(sum_tab_prev, quote=F)
Value Std.Error DF t-value p-value
prev~o*time_crtl_popdens 0.0072 0.0029 8798 2.4355 0.0149
prev~c*time_crtl_popdens 3e-04 0.003 8798 0.0945 0.9247
prev~e*time_crtl_popdens 0.0099 0.0029 8798 3.4019 7e-04
prev~a*time_crtl_popdens 0.0092 0.0029 8798 3.1338 0.0017
prev~n*time_crtl_popdens -0.0072 0.0029 8798 -2.4642 0.0137
prev~o*time_crtl_popdens*time 0.0099 0.0032 8797 3.0928 0.002
prev~c*time_crtl_popdens*time 1e-04 0.003 8797 0.0219 0.9825
prev~e*time_crtl_popdens*time 0.0104 0.0029 8797 3.5486 4e-04
prev~a*time_crtl_popdens*time 0.0091 0.0029 8797 3.1155 0.0018
prev~n*time_crtl_popdens*time -0.0073 0.0029 8797 -2.4725 0.0134
# social distancing
models_socdist <- list(models_o_socdist, 
                       models_c_socdist, 
                       models_e_socdist, 
                       models_a_socdist, 
                       models_n_socdist)

sum_tab_socdist <- summary_table(models_socdist, dv_name = 'socdist', prev=T)

write.table(sum_tab_socdist, quote=F)
Value Std.Error DF t-value p-value
socdist~o*time_crtl_popdens 0.0059 0.0016 8798 3.7756 2e-04
socdist~c*time_crtl_popdens -2e-04 0.0016 8798 -0.097 0.9227
socdist~e*time_crtl_popdens 0.0038 0.0016 8798 2.4132 0.0158
socdist~a*time_crtl_popdens 0.0022 0.0016 8798 1.4111 0.1582
socdist~n*time_crtl_popdens -0.0021 0.0016 8798 -1.3383 0.1808
socdist~o*time_crtl_popdens*time 0.0044 0.0017 8797 2.5576 0.0106
socdist~c*time_crtl_popdens*time 3e-04 0.0016 8797 0.1967 0.8441
socdist~e*time_crtl_popdens*time 0.0031 0.0016 8797 1.9928 0.0463
socdist~a*time_crtl_popdens*time 0.0023 0.0016 8797 1.5053 0.1323
socdist~n*time_crtl_popdens*time -0.0021 0.0016 8797 -1.3209 0.1866
socdist~o*time_crtl_popdens*time_prev 0.0033 0.0017 8796 1.9363 0.0529
socdist~c*time_crtl_popdens*time_prev 3e-04 0.0015 8796 0.1949 0.8455
socdist~e*time_crtl_popdens*time_prev 0.002 0.0016 8796 1.2797 0.2007
socdist~a*time_crtl_popdens*time_prev 0.0013 0.0015 8796 0.8453 0.398
socdist~n*time_crtl_popdens*time_prev -0.0012 0.0015 8796 -0.8056 0.4205

Conditional random forest analysis

Extract slopes prevalence


# slope prevalence
df_ger_slope_prev <- df_ger %>% split(.$kreis) %>% 
  map(~ lm(rate_day ~ time, data = .)) %>%
  map(coef) %>% 
  map_dbl('time') %>% 
  as.data.frame() %>% 
  rownames_to_column('kreis') %>% 
  rename(slope_prev = '.')

# merge with control variables 
df_ger_slope_prev <- df_ger %>% select(-time, -date, -rate_day, -socdist_single_tile) %>%
  distinct() %>% 
  inner_join(df_ger_slope_prev, by = 'kreis') %>%
  drop_na()

df_ger_slope_prev
NA

Extract slopes social distancing


# slope socdist
df_ger_slope_socdist <- df_ger %>% split(.$kreis) %>%
  map(~ lm(socdist_single_tile ~ time, data = .)) %>%
  map(coef) %>%
  map_dbl('time') %>%
  as.data.frame() %>%
  rownames_to_column('kreis') %>%
  rename(slope_socdist = '.')


# merge with control variables 
df_ger_slope_socdist <- df_ger %>% 
  select(-time, -date, -socdist_single_tile, -rate_day) %>%
  distinct() %>%
  inner_join(df_ger_slope_socdist, by = 'kreis') %>%
  drop_na()

df_ger_slope_socdist
NA

Explore distribution of slopes


df_ger_slope_prev %>% ggplot(aes(slope_prev)) + geom_histogram(bins = 100)


df_ger_slope_socdist %>% ggplot(aes(slope_socdist)) + geom_histogram(bins = 100)

NA
NA

CRF prevalence ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_prev <- cforest(slope_prev ~ pers_o + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_prev[-1], 
                         controls = ctrls)

crf_o_varimp_prev <- varimp(crf_o_fit_prev, nperm = 1)
crf_o_varimp_cond_prev <- varimp(crf_o_fit_prev, conditional = T, nperm = 1)

crf_o_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') +
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_prev <- cforest(slope_prev ~ pers_c + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_prev[-1], 
                         controls = ctrls)

crf_c_varimp_prev <- varimp(crf_c_fit_prev, nperm = 1)
crf_c_varimp_cond_prev <- varimp(crf_c_fit_prev, conditional = T, nperm = 1)

crf_c_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_prev <- cforest(slope_prev ~ pers_e + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_prev[-1], 
                         controls = ctrls)

crf_e_varimp_prev <- varimp(crf_e_fit_prev, nperm = 1)
crf_e_varimp_cond_prev <- varimp(crf_e_fit_prev, conditional = T, nperm = 1)

crf_e_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_prev <- cforest(slope_prev ~ pers_a + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_prev[-1], 
                         controls = ctrls)

crf_a_varimp_prev <- varimp(crf_a_fit_prev, nperm = 1)
crf_a_varimp_cond_prev <- varimp(crf_a_fit_prev, conditional = T, nperm = 1)

crf_a_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF prevalence ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_prev <- cforest(slope_prev ~ pers_n + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_prev[-1], 
                         controls = ctrls)

crf_n_varimp_prev <- varimp(crf_n_fit_prev, nperm = 1)
crf_n_varimp_cond_prev <- varimp(crf_n_fit_prev, conditional = T, nperm = 1)

crf_n_varimp_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_prev %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ openness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_o_fit_socdist <- cforest(slope_socdist ~ pers_o + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_socdist[-1], 
                         controls = ctrls)

crf_o_varimp_socdist <- varimp(crf_o_fit_socdist, nperm = 1)
crf_o_varimp_cond_socdist <- varimp(crf_o_fit_socdist, conditional = T, nperm = 1)

crf_o_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_o_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ conscientiousness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_c_fit_socdist <- cforest(slope_socdist ~ pers_c + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_socdist[-1], 
                         controls = ctrls)

crf_c_varimp_socdist <- varimp(crf_c_fit_socdist, nperm = 1)
crf_c_varimp_cond_socdist <- varimp(crf_c_fit_socdist, conditional = T, nperm = 1)

crf_c_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_c_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ extraversion


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_e_fit_socdist <- cforest(slope_socdist ~ pers_e + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_socdist[-1], 
                         controls = ctrls)

crf_e_varimp_socdist <- varimp(crf_e_fit_socdist, nperm = 1)
crf_e_varimp_cond_socdist <- varimp(crf_e_fit_socdist, conditional = T, nperm = 1)

crf_e_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_e_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ agreeableness


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_a_fit_socdist <- cforest(slope_socdist ~ pers_a + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_socdist[-1], 
                         controls = ctrls)

crf_a_varimp_socdist <- varimp(crf_a_fit_socdist, nperm = 1)
crf_a_varimp_cond_socdist <- varimp(crf_a_fit_socdist, conditional = T, nperm = 1)

crf_a_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_a_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

CRF social distancing ~ neuroticism


ctrls <- cforest_unbiased(ntree=500, mtry=5)

crf_n_fit_socdist <- cforest(slope_socdist ~ pers_n + women + academics +
                          hospital_beds + gdp + manufact +
                          airport + age + popdens, 
                         df_ger_slope_socdist[-1], 
                         controls = ctrls)

crf_n_varimp_socdist <- varimp(crf_n_fit_socdist, nperm = 1)
crf_n_varimp_cond_socdist <- varimp(crf_n_fit_socdist, conditional = T, nperm = 1)

crf_n_varimp_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))


crf_n_varimp_cond_socdist %>% as.data.frame() %>% rownames_to_column('variable') %>%
  ggplot(aes(x=variable, y=.)) +
  geom_bar(stat = 'identity') + 
  theme(axis.text.x = element_text(angle = 90))

Change point analysis

Preparation


# keep only counties with full data
kreis_complete <- df_ger_scaled %>% 
  group_by(kreis) %>% 
  summarize(n = n()) %>% 
  filter(n==max(.$n)) %>% 
  .$kreis

Prevalence

df_ger_cpt_prev %>% drop_na() %>% dim()
[1] 392  21

Social distancing

df_ger_cpt_prev_socdist %>% drop_na() %>% dim()
[1] 392  24

for(i in head(df_ger_socdist_cpt_results,5)){
  plot(i)
}

NA

Predicting change points

Linear models predicting change points (no controls)

lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n, data = df_ger_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.2799 -1.0828 -0.7745  1.5529  4.7123 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) 18.98750    0.07978 238.009  < 2e-16 ***
pers_o      -0.27313    0.08540  -3.198  0.00149 ** 
pers_c       0.10251    0.09059   1.132  0.25848    
pers_e       0.29762    0.09103   3.269  0.00117 ** 
pers_a       0.03447    0.09054   0.381  0.70365    
pers_n       0.22114    0.09398   2.353  0.01911 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.596 on 394 degrees of freedom
Multiple R-squared:  0.05102,   Adjusted R-squared:  0.03898 
F-statistic: 4.237 on 5 and 394 DF,  p-value: 0.0009179

Linear models predicting change points with controls

lm_cpt_socdist_pers %>% summary()

Call:
lm(formula = cpt_day_socdist ~ pers_o + pers_c + pers_e + pers_a + 
    pers_n + women + academics + hospital_beds + gdp + manufact + 
    airport + age + popdens, data = df_ger_cpt_prev_socdist)

Residuals:
    Min      1Q  Median      3Q     Max 
-2.9228 -1.0471 -0.5154  1.1130  4.2457 

Coefficients:
               Estimate Std. Error t value Pr(>|t|)    
(Intercept)   18.971592   0.074741 253.832  < 2e-16 ***
pers_o         0.005067   0.092110   0.055 0.956163    
pers_c         0.147269   0.089162   1.652 0.099427 .  
pers_e         0.313019   0.087348   3.584 0.000383 ***
pers_a         0.059518   0.089483   0.665 0.506368    
pers_n         0.112731   0.090458   1.246 0.213453    
women         -0.203951   0.100832  -2.023 0.043810 *  
academics     -0.215820   0.137713  -1.567 0.117910    
hospital_beds  0.217942   0.097882   2.227 0.026564 *  
gdp           -0.341968   0.162985  -2.098 0.036555 *  
manufact       0.387349   0.127592   3.036 0.002565 ** 
airport        0.244575   0.089491   2.733 0.006572 ** 
age            0.011052   0.109541   0.101 0.919687    
popdens        0.009737   0.118019   0.083 0.934290    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1.478 on 378 degrees of freedom
  (8 observations deleted due to missingness)
Multiple R-squared:  0.1979,    Adjusted R-squared:  0.1704 
F-statistic: 7.176 on 13 and 378 DF,  p-value: 1.515e-12
LS0tCnRpdGxlOiAiQ09WSUQxOSBHRVIiCmF1dGhvcjogIkhlaW5yaWNoIFBldGVycyIKZGF0ZTogIjQvMjMvMjAyMCIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUpCgojIE1BQwoga25pdHI6Om9wdHNfa25pdCRzZXQocm9vdC5kaXIgPSAnL1VzZXJzL2hwMjUwMC9Hb29nbGUgRHJpdmUvU1RVRFkvQ29sdW1iaWEvUmVzZWFyY2gvQ29yb25hL0RhdGEvR0VSJykKIApsaWJyYXJ5KGxtZXJUZXN0KQpsaWJyYXJ5KG5sbWUpCmxpYnJhcnkocHN5Y2gpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShkcGx5cikKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkocGFydHkpCgpgYGAKCiMgUHJlcGFyZSBkYXRhCgojIyMgUmVhZCBhbmQgZm9ybWF0IGRhdGEKYGBge3IgbWVzc2FnZT1GQUxTRX0KCmRmX2dlcl9jb3ZpZCA8LSByZWFkX2NzdignR2VybWFueV90aW1lc2VyaWVzX3ByZXAuY3N2JykKZGZfZ2VyX3NvY2Rpc3QgPC0gcmVhZF9jc3YoJ0dlcm1hbnlfc29jZGlzdF9mYl9rcmVpcy5jc3YnKQpkZl9nZXJfY3RybCA8LSByZWFkLmNzdjIoJ0dlcm1hbnlfY29udHJvbHMuY3N2Jywgc2VwID0gJzsnLCBkZWM9JywnKQoKYGBgCgoKYGBge3J9CgojIHByZXZhbGVuY2UgCmRmX2dlcl9jb3ZpZCA8LSBkZl9nZXJfY292aWQgJT4lIG11dGF0ZShkYXRlID0gYXMuRGF0ZShkYXRlLCAiJWQlYiVZIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrcmVpcyA9IGFzLmNoYXJhY3RlcihrcmVpcykpICU+JSAKICBkcGx5cjo6c2VsZWN0KC1ydW5kYXksIC1rcmVpc19uYW1lLCAtZXd6LCAtc2hhcGVfX2FyZWEsIAogICAgICAgICAgICAgICAgLWN1bWNhc2UsIC1hbnphaGxmYWxsLCAtcG9wZGVucykgJT4lCiAgZHBseXI6OnJlbmFtZShwZXJzX28gPSBvcGVuLCAKICAgICAgICAgcGVyc19jID0gc2NpLAogICAgICAgICBwZXJzX2UgPSBleHRyYSwKICAgICAgICAgcGVyc19hID0gYWdyZWUsCiAgICAgICAgIHBlcnNfbiA9IG5ldXJvKQoKZGZfZ2VyX2NvdmlkCmBgYAoKCmBgYHtyfQoKIyBzb2NpYWwgZGlzdGFuY2luZwpkZl9nZXJfc29jZGlzdCA8LSBkZl9nZXJfc29jZGlzdCAlPiUgCiAgcmVuYW1lKHNvY2Rpc3Rfc2luZ2xlX3RpbGUgPSBhbGxfZGF5X3JhdGlvX3NpbmdsZV90aWxlX3VzZXJzKSAlPiUKICBzZWxlY3Qoa3JlaXMsIGRhdGUsIHNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JSAKICBtdXRhdGUoa3JlaXMgPSBhcy5jaGFyYWN0ZXIoa3JlaXMpKQoKZGZfZ2VyX3NvY2Rpc3QKCmBgYAoKCmBgYHtyfQojIGNvbnRyb2xzIApkZl9nZXJfY3RybCA8LSBkZl9nZXJfY3RybCAlPiUgc2VsZWN0KC1rcmVpc19ubWUpICU+JQogICAgbXV0YXRlKGtyZWlzID0gYXMuY2hhcmFjdGVyKGtyZWlzKSwKICAgICAgICAgICBwb3BkZW5zID0gcG9wZGVucyAlPiUgCiAgICAgICAgICAgICBhcy5jaGFyYWN0ZXIoKSAlPiUKICAgICAgICAgICAgIHN0cl9yZXBsYWNlKCdcXC4nLCAnJyklPiUKICAgICAgICAgICAgIGFzLm51bWVyaWMoKSkKCmRmX2dlcl9jdHJsCgoKYGBgCgoKYGBge3J9CgojIG1lcmdlCmRmX2dlciA8LSBkZl9nZXJfY292aWQgJT4lIAogIGlubmVyX2pvaW4oZGZfZ2VyX3NvY2Rpc3QsIGJ5ID0gYygna3JlaXMnLCAnZGF0ZScpKSAlPiUgCiAgaW5uZXJfam9pbihkZl9nZXJfY3RybCwgYnkgPSAna3JlaXMnKQoKIyBrZWVwIG9ubHkgY291bnRpZXMgd2l0aCBmdWxsIGRhdGEKa3JlaXNfY29tcGxldGUgPC0gZGZfZ2VyICU+JSAKICBncm91cF9ieShrcmVpcykgJT4lIAogIHN1bW1hcml6ZShuID0gbigpKSAlPiUgCiAgZmlsdGVyKG49PW1heCguJG4pKSAlPiUgCiAgLiRrcmVpcwoKZGZfZ2VyIDwtIGRmX2dlciAlPiUgZmlsdGVyKGtyZWlzICVpbiUga3JlaXNfY29tcGxldGUpCgojIGNyZWF0ZSBzZXF1ZW5jZSBvZiBkYXRlcwpkYXRlX3NlcXVlbmNlIDwtIHNlcS5EYXRlKG1pbihkZl9nZXIkZGF0ZSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgbWF4KGRmX2dlciRkYXRlKSwgMSkKICAgICAgICAgICAgICAgICAgICAgCiMgY3JlYXRlIGRhdGEgZnJhbWUgd2l0aCB0aW1lIHNlcXVlbmNlCmRmX2RhdGVzID0gdGliYmxlKGRhdGVfc2VxdWVuY2UsIDE6bGVuZ3RoKGRhdGVfc2VxdWVuY2UpKSAKbmFtZXMoZGZfZGF0ZXMpIDwtIGMoJ2RhdGUnLCAndGltZScpCgojIG1lcmdlIGRheSBpbmRleCB3aXRoIGdwcyBkYXRhCmRmX2dlciA9IGRmX2dlciAlPiUgCiAgbWVyZ2UoZGZfZGF0ZXMsIGJ5PSdkYXRlJykgJT4lIAogIGFycmFuZ2Uoa3JlaXMpICU+JQogIGFzX3RpYmJsZSgpCgpgYGAKCgojIEV4cGxvcmUgZGF0YQoKIyMjIFBsb3QgcHJldmFsZW5jZSBvdmVyIHRpbWUKYGBge3J9CgpkZl9nZXIgJT4lIGdncGxvdChhZXMoeD10aW1lLCB5PXJhdGVfZGF5KSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2w9a3JlaXMsIHNpemU9cG9wZGVucykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPVQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoIk92ZXJhbGwgcHJldmFsZW5jZSBvdmVyIHRpbWUiKQoKcGVycyA8LSBjKCdwZXJzX28nLCAncGVyc19jJywgJ3BlcnNfZScsICdwZXJzX2EnLCAncGVyc19uJykKCmZvciAoaSBpbiBwZXJzKXsKCmdnIDwtIGRmX2dlciAlPiUgbXV0YXRlKHByZXZfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4yKSwgcXVhbnRpbGUoLltbaV1dLCAwLjgpLCBJbmYpLAogICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKHByZXZfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9cmF0ZV9kYXkpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1rcmVpcywgc2l6ZT1wb3BkZW5zKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICBmYWNldF93cmFwKH5wcmV2X3RhaWwpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoaSkKCnByaW50KGdnKQp9CgpgYGAKCgojIyMgUGxvdCBzb2NpYWwgZGlzdGFuY2luZyAoc2luZ2xlIHRpbGUpIG92ZXIgdGltZQpgYGB7cn0KCmRmX2dlciAlPiUgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZSkpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWtyZWlzLCBzaXplPXBvcGRlbnMpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbj0ibm9uZSIpICsKICBnZ3RpdGxlKCJPdmVyYWxsIHNvY2lhbCBkaXN0YW5jaW5nIChzaW5nbGUgdGlsZSkgb3ZlciB0aW1lIikKCnBlcnMgPC0gYygncGVyc19vJywgJ3BlcnNfYycsICdwZXJzX2UnLCAncGVyc19hJywgJ3BlcnNfbicpCgpmb3IgKGkgaW4gcGVycyl7CgpnZyA8LSBkZl9nZXIgJT4lIG11dGF0ZShwcmV2X3RhaWwgPSBjdXQoLltbaV1dLCAKICAgICAgYnJlYWtzID0gYygtSW5mLCBxdWFudGlsZSguW1tpXV0sIDAuMiksIHF1YW50aWxlKC5bW2ldXSwgMC44KSwgSW5mKSwKICAgICAgbGFiZWxzID0gYygnbG93ZXIgdGFpbCcsICdjZW50ZXInLCAndXBwZXIgdGFpbCcpKSkgJT4lIAogIGZpbHRlcihwcmV2X3RhaWwgIT0gJ2NlbnRlcicpICU+JQogIGdncGxvdChhZXMoeD10aW1lLCB5PXNvY2Rpc3Rfc2luZ2xlX3RpbGUpKSArIAogIGdlb21fcG9pbnQoYWVzKGNvbD1rcmVpcywgc2l6ZT1wb3BkZW5zKSkgKyAKICBnZW9tX3Ntb290aChtZXRob2Q9ImxvZXNzIiwgc2U9VCkgKyAKICBmYWNldF93cmFwKH5wcmV2X3RhaWwpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoaSkKCnByaW50KGdnKQp9CgpgYGAKCiMjIyBDb250cm9sIGZvciB3ZWVrZW5kIGVmZmVjdCAKCmBgYHtyfQoKZGZfZ2VyX2xvZXNzIDwtIGRmX2dlciAlPiUgCiAgbXV0YXRlKHdlZWtkYXkgPSBmb3JtYXQoZGF0ZSwgJyV1JykpICU+JSAKICBmaWx0ZXIoIXdlZWtkYXkgJWluJSBjKCc2JywnNycpKSAlPiUgCiAgc3BsaXQoLiRrcmVpcykgJT4lCiAgbWFwKH4gbG9lc3Moc29jZGlzdF9zaW5nbGVfdGlsZSB+IHRpbWUsIGRhdGEgPSAuKSkgJT4lCiAgbWFwKHByZWRpY3QsIDE6bWF4KGRmX2dlciR0aW1lKSkgJT4lIAogIGJpbmRfcm93cygpICU+JSAKICBnYXRoZXIoa2V5ID0gJ2tyZWlzJywgdmFsdWUgPSAnbG9lc3MnKSAlPiUgCiAgZ3JvdXBfYnkoa3JlaXMpICU+JSAKICBtdXRhdGUodGltZSA9IHJvd19udW1iZXIoKSkKCmRmX2dlcl9sb2VzcwoKZGZfZ2VyIDwtIGRmX2dlciAlPiUgbWVyZ2UoZGZfZ2VyX2xvZXNzLCBieT1jKCdrcmVpcycsICd0aW1lJykpICU+JSAKICBtdXRhdGUod2Vla2RheSA9IGZvcm1hdChkYXRlLCAnJXUnKSkgJT4lIAogIG11dGF0ZShzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuID0gaWZlbHNlKHdlZWtkYXkgJWluJSBjKCc2JywnNycpLCBsb2VzcywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzb2NkaXN0X3NpbmdsZV90aWxlKSkgJT4lCiAgYXJyYW5nZShrcmVpcywgdGltZSkgJT4lIAogIHNlbGVjdCgtd2Vla2RheSkKCmRmX2dlciAlPiUgZHJvcF9uYSgpCgpgYGAKCmBgYHtyfQoKZGZfZ2VyICU+JSBnZ3Bsb3QoYWVzKHg9dGltZSwgeT1zb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuKSkgKyAKICBnZW9tX3BvaW50KGFlcyhjb2w9a3JlaXMsIHNpemU9cG9wZGVucykpICsgCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsb2VzcyIsIHNlPVQpICsgCiAgdGhlbWUobGVnZW5kLnBvc2l0aW9uPSJub25lIikgKwogIGdndGl0bGUoIk92ZXJhbGwgc29jaWFsIGRpc3RhbmNpbmcgKHNpbmdsZSB0aWxlKSBvdmVyIHRpbWUiKQoKcGVycyA8LSBjKCdwZXJzX28nLCAncGVyc19jJywgJ3BlcnNfZScsICdwZXJzX2EnLCAncGVyc19uJykKCmZvciAoaSBpbiBwZXJzKXsKCmdnIDwtIGRmX2dlciAlPiUgbXV0YXRlKHByZXZfdGFpbCA9IGN1dCguW1tpXV0sIAogICAgICBicmVha3MgPSBjKC1JbmYsIHF1YW50aWxlKC5bW2ldXSwgMC4yKSwgcXVhbnRpbGUoLltbaV1dLCAwLjgpLCBJbmYpLAogICAgICBsYWJlbHMgPSBjKCdsb3dlciB0YWlsJywgJ2NlbnRlcicsICd1cHBlciB0YWlsJykpKSAlPiUgCiAgZmlsdGVyKHByZXZfdGFpbCAhPSAnY2VudGVyJykgJT4lCiAgZ2dwbG90KGFlcyh4PXRpbWUsIHk9c29jZGlzdF9zaW5nbGVfdGlsZV9jbGVhbikpICsgCiAgZ2VvbV9wb2ludChhZXMoY29sPWtyZWlzLCBzaXplPXBvcGRlbnMpKSArIAogIGdlb21fc21vb3RoKG1ldGhvZD0ibG9lc3MiLCBzZT1UKSArIAogIGZhY2V0X3dyYXAofnByZXZfdGFpbCkgKyAKICB0aGVtZShsZWdlbmQucG9zaXRpb249Im5vbmUiKSArCiAgZ2d0aXRsZShpKQoKcHJpbnQoZ2cpCn0KCmBgYAoKCmBgYHtyfQoKZGZfZ2VyIDwtIGRmX2dlciAlPiUgbXV0YXRlKHNvY2Rpc3Rfc2luZ2xlX3RpbGUgPSBzb2NkaXN0X3NpbmdsZV90aWxlX2NsZWFuKSAlPiUgCiAgc2VsZWN0KC1sb2VzcywgLXNvY2Rpc3Rfc2luZ2xlX3RpbGVfY2xlYW4pCgpgYGAKCgojIyMgQ29ycmVsYXRpb25zCmBgYHtyfQoKZGZfZ2VyICU+JSBncm91cF9ieShrcmVpcykgJT4lIAogIHN1bW1hcml6ZV9pZihpcy5udW1lcmljLCBtZWFuKSAlPiUgCiAgc2VsZWN0KC1rcmVpcywgLXRpbWUpICU+JSAKICBjb3IodXNlPSdwYWlyd2lzZS5jb21wbGV0ZScpICU+JSAKICByb3VuZCgzKQogCmBgYAoKIyBNb2RlbGxpbmcgCiMjIFByZXBhcmUgZnVuY3Rpb25zCgpgYGB7cn0KCiMgZnVuY3Rpb24gY2FsY3VsYXRlcyBhbGwgcmVsZXZhbnQgbW9kZWxzCnJ1bl9tb2RlbHMgPC0gZnVuY3Rpb24oeSwgbHZsMV94LCBsdmwyX3gsIGx2bDJfaWQsIGRhdGEsIGN0cmxzPUYpewoKICAjIHN1YnNldCBkYXRhCiAgZGF0YSA9IGRhdGEgJT4lIAogICAgZHBseXI6OnNlbGVjdChhbGxfb2YoeSksIGFsbF9vZihsdmwxX3gpLCBhbGxfb2YobHZsMl94KSwgYWxsX29mKGx2bDJfaWQpLCAKICAgICAgICAgICAgICAgICAgcG9wZGVucywgcmF0ZV9kYXkpCiAgZGF0YSA9IGRhdGEgJT4lIAogICAgZHBseXI6OnJlbmFtZSh5ID0gYWxsX29mKHkpLAogICAgICAgICAgIGx2bDFfeCA9IGFsbF9vZihsdmwxX3gpLAogICAgICAgICAgIGx2bDJfeCA9IGFsbF9vZihsdmwyX3gpLAogICAgICAgICAgIGx2bDJfaWQgPSBhbGxfb2YobHZsMl9pZCkKICAgICAgICAgICApCiAgCiAgIyBjb25maWd1cmUgb3B0aW1pemF0aW9uIHByb2NlZHVyZQogIGN0cmxfY29uZmlnIDwtIGxtZUNvbnRyb2wob3B0ID0gJ29wdGltJywgbWF4SXRlciA9IDEwMCwgbXNNYXhJdGVyID0gMTAwKQoKICAjIGJhc2VsaW5lCiAgYmFzZWxpbmUgPC0gbG1lKGZpeGVkID0geSB+IDEsIHJhbmRvbSA9IH4gMSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKCiAgIyByYW5kb20gaW50ZXJjZXB0IGZpeGVkIHNsb3BlCiAgcmFuZG9tX2ludGVyY2VwdCA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICsgbHZsMl94LCAKICAgICAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IDEgfCBsdmwyX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCgogICMgcmFuZG9tIGludGVyY2VwdCByYW5kb20gc2xvcGUKICByYW5kb21fc2xvcGUgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgICByYW5kb20gPSB+IGx2bDFfeCB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQoKICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgaW50ZXJhY3Rpb24gPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCwgCiAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgcmVzdWx0cyA8LSBsaXN0KCdiYXNlbGluZScgPSBiYXNlbGluZSwgCiAgICAgICAgICAgICAgICAgICJyYW5kb21faW50ZXJjZXB0IiA9IHJhbmRvbV9pbnRlcmNlcHQsIAogICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uIiA9IGludGVyYWN0aW9uKQogIAogIAogIGlmIChjdHJscyA9PSAnZGVtJyB8IGN0cmxzID09ICdwcmV2Jyl7CiAgICAKICAgICMgcmFuZG9tIGludGVyY2VwdCByYW5kb20gc2xvcGUKICAgIHJhbmRvbV9zbG9wZV9jdHJsX2RlbSA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICsgbHZsMl94ICsgcG9wZGVucywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAgICMgY3Jvc3MgbGV2ZWwgaW50ZXJhY3Rpb24KICAgIGludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0gPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCArIHBvcGRlbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpCiAgCiAgICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgICBpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0gPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCAqIGx2bDJfeCArIGx2bDFfeCAqIHBvcGRlbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggfCBsdmwyX2lkLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgICBjb250cm9sID0gY3RybF9jb25maWcsCiAgICAgICAgICAgICAgICAgIG1ldGhvZCA9ICdNTCcpICAgICAgICAKICAgIAogICAgIyBjcmVhdGUgbGlzdCB3aXRoIHJlc3VsdHMKICAgIHJlc3VsdHMgPC0gbGlzdCgnYmFzZWxpbmUnID0gYmFzZWxpbmUsIAogICAgICAgICAgICAgICAgICAgICJyYW5kb21faW50ZXJjZXB0IiA9IHJhbmRvbV9pbnRlcmNlcHQsIAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGUiID0gcmFuZG9tX3Nsb3BlLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbiIgPSBpbnRlcmFjdGlvbiwKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlX2N0cmxfZGVtIiA9IHJhbmRvbV9zbG9wZV9jdHJsX2RlbSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSIgPSBpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtLAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW0iID0gaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtKQogIH0KICAKICBpZiAoY3RybHMgPT0gJ3ByZXYnKXsKICAKICAgICMgcmFuZG9tIGludGVyY2VwdCByYW5kb20gc2xvcGUKICAgIHJhbmRvbV9zbG9wZV9jdHJsX3ByZXYgPC0gbG1lKGZpeGVkID0geSB+IGx2bDFfeCArIGx2bDJfeCArIHBvcGRlbnMgKyByYXRlX2RheSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggKyByYXRlX2RheSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkYXRhLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKSAgCiAgICAKICAgICAgICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgICBpbnRlcmFjdGlvbl9jdHJsX21haW5fcHJldiA8LSBsbWUoZml4ZWQgPSB5IH4gbHZsMV94ICogbHZsMl94ICsgcG9wZGVucyArIHJhdGVfZGF5LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gbHZsMV94IHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgIGNvcnJlbGF0aW9uID0gY29yQVIxKCksCiAgICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQogIAogIAogICAgIyBjcm9zcyBsZXZlbCBpbnRlcmFjdGlvbgogICAgaW50ZXJhY3Rpb25fY3RybF9pbnRfcHJldjwtIGxtZShmaXhlZCA9IHkgfiBsdmwxX3ggKiBsdmwyX3ggKyBsdmwxX3ggKiBwb3BkZW5zICsgcmF0ZV9kYXksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiBsdmwxX3ggKyByYXRlX2RheSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgICBjb3JyZWxhdGlvbiA9IGNvckFSMSgpLAogICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2wgPSBjdHJsX2NvbmZpZywKICAgICAgICAgICAgICAgICAgbWV0aG9kID0gJ01MJykKICAKICAgICMgY3JlYXRlIGxpc3Qgd2l0aCByZXN1bHRzCiAgICByZXN1bHRzIDwtIGxpc3QoJ2Jhc2VsaW5lJyA9IGJhc2VsaW5lLCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX2ludGVyY2VwdCIgPSByYW5kb21faW50ZXJjZXB0LCAKICAgICAgICAgICAgICAgICAgICAicmFuZG9tX3Nsb3BlIiA9IHJhbmRvbV9zbG9wZSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb24iID0gaW50ZXJhY3Rpb24sCiAgICAgICAgICAgICAgICAgICAgInJhbmRvbV9zbG9wZV9jdHJsX2RlbSIgPSByYW5kb21fc2xvcGVfY3RybF9kZW0sCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfbWFpbl9kZW0iID0gaW50ZXJhY3Rpb25fY3RybF9tYWluX2RlbSwKICAgICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb25fY3RybF9pbnRfZGVtIiA9IGludGVyYWN0aW9uX2N0cmxfaW50X2RlbSwgICAgICAgICAgICAgICAgICAgIAogICAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGVfY3RybF9wcmV2IiA9IHJhbmRvbV9zbG9wZV9jdHJsX3ByZXYsCiAgICAgICAgICAgICAgICAgICAgImludGVyYWN0aW9uX2N0cmxfbWFpbl9wcmV2IiA9IGludGVyYWN0aW9uX2N0cmxfbWFpbl9wcmV2LAogICAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9jdHJsX2ludF9wcmV2IiA9IGludGVyYWN0aW9uX2N0cmxfaW50X3ByZXYpCiAgfQogIAogIGlmKGN0cmxzID09ICdleHAnKXsKICAgICMgcmFuZG9tIGludGVyY2VwdCByYW5kb20gc2xvcGUKICByYW5kb21fc2xvcGVfZXhwIDwtIGxtZShmaXhlZCA9IHkgfiAobHZsMV94ICsgSShsdmwxX3heMikpICsgbHZsMl94LCAKICAgICAgICAgICAgICAgICAgICAgIHJhbmRvbSA9IH4gKGx2bDFfeCArIEkobHZsMV94XjIpKSB8IGx2bDJfaWQsIAogICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGF0YSwKICAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKQoKICAjIGNyb3NzIGxldmVsIGludGVyYWN0aW9uCiAgaW50ZXJhY3Rpb25fZXhwIDwtIGxtZShmaXhlZCA9IHkgfiAobHZsMV94ICsgSShsdmwxX3heMikpICogbHZsMl94LCAKICAgICAgICAgICAgICAgICAgICAgcmFuZG9tID0gfiAobHZsMV94ICsgSShsdmwxX3heMikpIHwgbHZsMl9pZCwgCiAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRhdGEsCiAgICAgICAgICAgICAgICAgICAgICAgY29ycmVsYXRpb24gPSBjb3JBUjEoKSwKICAgICAgICAgICAgICAgICAgY29udHJvbCA9IGN0cmxfY29uZmlnLAogICAgICAgICAgICAgICAgICBtZXRob2QgPSAnTUwnKSAgCiAgCiAgCiAgIyBjcmVhdGUgbGlzdCB3aXRoIHJlc3VsdHMKICByZXN1bHRzIDwtIGxpc3QoJ2Jhc2VsaW5lJyA9IGJhc2VsaW5lLCAKICAgICAgICAgICAgICAgICAgInJhbmRvbV9pbnRlcmNlcHQiID0gcmFuZG9tX2ludGVyY2VwdCwgCiAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGUiID0gcmFuZG9tX3Nsb3BlLAogICAgICAgICAgICAgICAgICAiaW50ZXJhY3Rpb24iID0gaW50ZXJhY3Rpb24sICAgICAgICAgICAgICAgICAgCiAgICAgICAgICAgICAgICAgICJyYW5kb21fc2xvcGVfZXhwIiA9IHJhbmRvbV9zbG9wZV9leHAsCiAgICAgICAgICAgICAgICAgICJpbnRlcmFjdGlvbl9leHAiID0gaW50ZXJhY3Rpb25fZXhwKQogIH0KICAKICByZXR1cm4ocmVzdWx0cykKICAgICAgICAKfQoKIyBleHRyYWN0cyB0YWJsZSB3aXRoIGNvZWZmaWNpZW50cyBhbmQgdGVzdHMgc3RhdGlzdGljcwpleHRyYWN0X3Jlc3VsdHMgPC0gZnVuY3Rpb24obW9kZWxzKSB7CiAgCiAgbW9kZWxzX3N1bW1hcnkgPC0gbW9kZWxzICU+JSAKICBtYXAoc3VtbWFyeSkgJT4lIAogIG1hcCgidFRhYmxlIikgJT4lIAogIG1hcChhcy5kYXRhLmZyYW1lKSAlPiUgCiAgbWFwKHJvdW5kLCAxMCkgCiAgIyAlPiUgbWFwKH4gLltzdHJfZGV0ZWN0KHJvd25hbWVzKC4pLCAnSW50ZXJ8bHZsJyksXSkKICAKICByZXR1cm4obW9kZWxzX3N1bW1hcnkpCiAgCn0KCgpjb21wYXJlX21vZGVscyA8LSBmdW5jdGlvbihtb2RlbHMpIHsKCiAgbWRsX25hbWVzIDwtIG1vZGVscyAlPiUgbmFtZXMoKQogIAogIHN0ciA9ICcnCiAgZm9yIChpIGluIG1kbF9uYW1lcyl7CiAgICAKICAgIG1kbF9zdHIgPC0gcGFzdGUoJ21vZGVscyQnLCBpLCBzZXAgPSAnJykKICAgIAogICAgaWYoaSA9PSAnYmFzZWxpbmUnKXsKICAgICAgc3RyIDwtIG1kbF9zdHIKICAgIH1lbHNlewogICAgc3RyIDwtIHBhc3RlKHN0ciwgbWRsX3N0ciwgc2VwPScsICcpCiAgICB9CiAgfQogIAogIGFub3ZhX3N0ciA8LSBwYXN0ZTAoJ2Fub3ZhKCcsIHN0ciwgJyknKQogIG1kbF9jb21wIDwtIGV2YWwocGFyc2UodGV4dD1hbm92YV9zdHIpKQogIHJvd25hbWVzKG1kbF9jb21wKSA9IG1kbF9uYW1lcwogIHJldHVybihtZGxfY29tcCkKfQoKCmBgYAoKIyMgUmVzY2FsZSBEYXRhCmBgYHtyfQoKbHZsMl9zY2FsZWQgPC0gZGZfZ2VyICU+JSAKICBkcGx5cjo6c2VsZWN0KC10aW1lLCAtcmF0ZV9kYXksIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtZGF0ZSkgJT4lIAogIGRpc3RpbmN0KCkgJT4lIAogIG11dGF0ZV9hdCh2YXJzKC1rcmVpcyksIHNjYWxlKQogIApsdmwxX3NjYWxlZCA8LSBkZl9nZXIgJT4lIHNlbGVjdChrcmVpcywgdGltZSwgcmF0ZV9kYXksIHNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JSAKICBtdXRhdGVfYXQodmFycygta3JlaXMsIC10aW1lKSwgc2NhbGUpCgpkZl9nZXJfc2NhbGVkIDwtIHBseXI6OmpvaW4obHZsMV9zY2FsZWQsIGx2bDJfc2NhbGVkLCBieSA9ICdrcmVpcycpCgpoZWFkKGRmX2dlcl9zY2FsZWQpCgoKYGBgCgoKCiMjIFByZWRpY3QgcHJldmFsZW5jZQojIyMgcHJldmFsZW5jZSB+IG9wZW5uZXNzCmBgYHtyfQoKbW9kZWxzX29fY292aWQgPC1ydW5fbW9kZWxzKHkgPSAncmF0ZV9kYXknLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19vJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2tyZWlzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfZ2VyX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ2RlbScpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX29fY292aWQpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfb19jb3ZpZCkKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBjb25zY2llbnRpb3VzbmVzcwpgYGB7cn0KCm1vZGVsc19jX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfYycsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19jX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2NfY292aWQpCgoKYGBgCgojIyMgcHJldmFsZW5jZSB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCm1vZGVsc19lX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX2VfY292aWQpCgoKYGBgCgojIyMgcHJldmFsZW5jZSB+IGFncmVlYWJsZW5lc3MKYGBge3J9Cgptb2RlbHNfYV9jb3ZpZCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2EnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9nZXJfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZGVtJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfYV9jb3ZpZCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19hX2NvdmlkKQoKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBuZXVyb3RpY2lzbQpgYGB7cn0KCm1vZGVsc19uX2NvdmlkIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfbicsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdkZW0nKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19uX2NvdmlkKQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX25fY292aWQpCgoKYGBgCgojIyBQcmVkaWN0IHNvY2lhbCBkaXN0YW5jaW5nCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IG9wZW5uZXNzCmBgYHtyfQoKbW9kZWxzX29fc29jZGlzdCA8LXJ1bl9tb2RlbHMoeSA9ICdzb2NkaXN0X3NpbmdsZV90aWxlJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfbycsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdwcmV2JykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfb19zb2NkaXN0KQoKY29tcGFyZV9tb2RlbHMobW9kZWxzX29fc29jZGlzdCkKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9Cgptb2RlbHNfY19zb2NkaXN0IDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19jJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2tyZWlzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfZ2VyX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ3ByZXYnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19jX3NvY2Rpc3QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfY19zb2NkaXN0KQoKCgpgYGAKCiMjIyBzb2NpYWwgZGlzdGFuY2luZyB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCm1vZGVsc19lX3NvY2Rpc3QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2UnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9nZXJfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2Vfc29jZGlzdCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX3NvY2Rpc3QpCgoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gYWdyZWVhYmxlbmVzcwpgYGB7cn0KCm1vZGVsc19hX3NvY2Rpc3QgPC1ydW5fbW9kZWxzKHkgPSAnc29jZGlzdF9zaW5nbGVfdGlsZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2EnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9nZXJfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAncHJldicpCgpleHRyYWN0X3Jlc3VsdHMobW9kZWxzX2Ffc29jZGlzdCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19hX3NvY2Rpc3QpCgoKCmBgYAoKIyMjIHNvY2lhbCBkaXN0YW5jaW5nIH4gbmV1cm90aWNpc20KYGBge3J9Cgptb2RlbHNfbl9zb2NkaXN0IDwtcnVuX21vZGVscyh5ID0gJ3NvY2Rpc3Rfc2luZ2xlX3RpbGUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDFfeCA9ICd0aW1lJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19uJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX2lkID0gJ2tyZWlzJywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfZ2VyX3NjYWxlZCwKICAgICAgICAgICAgICAgICAgICAgICAgIGN0cmxzID0gJ3ByZXYnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19uX3NvY2Rpc3QpCgpjb21wYXJlX21vZGVscyhtb2RlbHNfbl9zb2NkaXN0KQoKCmBgYAoKIyMgRXhwbG9yZSBxdWFkcmF0aWMgdHJlbmRzIAoKIyMjIHByZXZhbGVuY2UgfiBvcGVubmVzcwpgYGB7cn0KCm1vZGVsc19vX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwyX3ggPSAncGVyc19vJywKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19vX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19vX2NvdmlkX2V4cCkKCmBgYAoKCiMjIHByZXZhbGVuY2UgfiBjb25zY2llbnRpb3VzbmVzcwpgYGB7cn0KCm1vZGVsc19jX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX2MnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9nZXJfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZXhwJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfY19jb3ZpZF9leHApCgpjb21wYXJlX21vZGVscyhtb2RlbHNfY19jb3ZpZF9leHApCgpgYGAKCiMjIyBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKbW9kZWxzX2VfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19lX2NvdmlkX2V4cCkKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKbW9kZWxzX2FfY292aWRfZXhwIDwtcnVuX21vZGVscyh5ID0gJ3JhdGVfZGF5JywgCiAgICAgICAgICAgICAgICAgICAgICAgICBsdmwxX3ggPSAndGltZScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl94ID0gJ3BlcnNfYScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMl9pZCA9ICdrcmVpcycsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9zY2FsZWQsCiAgICAgICAgICAgICAgICAgICAgICAgICBjdHJscyA9ICdleHAnKQoKZXh0cmFjdF9yZXN1bHRzKG1vZGVsc19hX2NvdmlkX2V4cCkKCmNvbXBhcmVfbW9kZWxzKG1vZGVsc19hX2NvdmlkX2V4cCkKCmBgYAoKIyMjIHByZXZhbGVuY2UgfiBuZXVyb3RpY2lzbQpgYGB7cn0KCm1vZGVsc19uX2NvdmlkX2V4cCA8LXJ1bl9tb2RlbHMoeSA9ICdyYXRlX2RheScsIAogICAgICAgICAgICAgICAgICAgICAgICAgbHZsMV94ID0gJ3RpbWUnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfeCA9ICdwZXJzX24nLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGx2bDJfaWQgPSAna3JlaXMnLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSBkZl9nZXJfc2NhbGVkLAogICAgICAgICAgICAgICAgICAgICAgICAgY3RybHMgPSAnZXhwJykKCmV4dHJhY3RfcmVzdWx0cyhtb2RlbHNfbl9jb3ZpZF9leHApCgpjb21wYXJlX21vZGVscyhtb2RlbHNfbl9jb3ZpZF9leHApCgpgYGAKCiMjIENyZWF0ZSBvdmVydmlldyB0YWJsZSAKCiMjIyBEZWZpbmUgZnVuY3Rpb24gdG8gY3JlYXRlIG92ZXJ2aWV3IHRhYmxlcwpgYGB7cn0KCnN1bW1hcnlfdGFibGUgPC0gZnVuY3Rpb24obW9kZWxzLCBkdl9uYW1lLCBwcmV2PUYpewoKICB0ZW1wX2RmX2N0cmxfbWFpbiA8LSBOVUxMCiAgdGVtcF9kZl9jdHJsX2ludCA8LSBOVUxMCiAgdGVtcF9kZl9jdHJsX2ludF9wcmV2IDwtIE5VTEwKICAKICBmb3IgKGkgaW4gbW9kZWxzKXsKICAgIHJlc3VsdHMgPC0gaSAlPiUgZXh0cmFjdF9yZXN1bHRzKCkKICAgIAogICAgcmVzdWx0c19jdHJsX21haW4gPC0gcmVzdWx0cyRpbnRlcmFjdGlvbl9jdHJsX21haW5fZGVtWydsdmwxX3g6bHZsMl94JyxdCiAgICB0ZW1wX2RmX2N0cmxfbWFpbiA8LSB0ZW1wX2RmX2N0cmxfbWFpbiAlPiUgcmJpbmQocmVzdWx0c19jdHJsX21haW4pCiAgICAKICAgIHJlc3VsdHNfY3RybF9pbnQgPC0gcmVzdWx0cyRpbnRlcmFjdGlvbl9jdHJsX2ludF9kZW1bJ2x2bDFfeDpsdmwyX3gnLF0KICAgIHRlbXBfZGZfY3RybF9pbnQgPC0gdGVtcF9kZl9jdHJsX2ludCAlPiUgcmJpbmQocmVzdWx0c19jdHJsX2ludCkKICAgIAogICAgaWYocHJldil7CiAgICAgIHJlc3VsdHNfY3RybF9pbnRfcHJldiA8LSByZXN1bHRzJGludGVyYWN0aW9uX2N0cmxfaW50X3ByZXZbJ2x2bDFfeDpsdmwyX3gnLF0KICAgICAgdGVtcF9kZl9jdHJsX2ludF9wcmV2IDwtIHRlbXBfZGZfY3RybF9pbnRfcHJldiAlPiUgcmJpbmQocmVzdWx0c19jdHJsX2ludF9wcmV2KQogICAgfQogICAgICAgIAogIH0KICAKICBuYW1lc19jdHJsX21haW4gPC0gcGFzdGUwKGR2X25hbWUsICd+JywgYygnbycsICdjJywgJ2UnLCAnYScsICduJyksICcqdGltZScsICdfY3J0bF9wb3BkZW5zJykKICByb3duYW1lcyh0ZW1wX2RmX2N0cmxfbWFpbikgPC0gbmFtZXNfY3RybF9tYWluCgogIG5hbWVzX2N0cmxfaW50IDwtIHBhc3RlMChkdl9uYW1lLCAnficsIGMoJ28nLCAnYycsICdlJywgJ2EnLCAnbicpLCAnKnRpbWUnLCAnX2NydGxfcG9wZGVucyp0aW1lJykKICByb3duYW1lcyh0ZW1wX2RmX2N0cmxfaW50KSA8LSBuYW1lc19jdHJsX2ludAoKICBpZihwcmV2KXsKICAgIG5hbWVzX2N0cmxfaW50X3ByZXYgPC0gcGFzdGUwKGR2X25hbWUsICd+JywgYygnbycsICdjJywgJ2UnLCAnYScsICduJyksICcqdGltZScsICdfY3J0bF9wb3BkZW5zKnRpbWVfcHJldicpCiAgICByb3duYW1lcyh0ZW1wX2RmX2N0cmxfaW50X3ByZXYpIDwtIG5hbWVzX2N0cmxfaW50X3ByZXYKICAgIAogICAgc3VtX3RhYiA8LSByYmluZCh0ZW1wX2RmX2N0cmxfbWFpbiwgdGVtcF9kZl9jdHJsX2ludCwgdGVtcF9kZl9jdHJsX2ludF9wcmV2KSAlPiUgcm91bmQoNCkKICB9ZWxzZXsKICAgIHN1bV90YWIgPC0gcmJpbmQodGVtcF9kZl9jdHJsX21haW4sIHRlbXBfZGZfY3RybF9pbnQpICU+JSByb3VuZCg0KQogIH0KCgogIAogIHJldHVybihzdW1fdGFiKQoKfSAKCmBgYAoKIyMjIENyZWF0ZSBvdmVydmlldyB0YWJsZXMKYGBge3J9CiMgcHJldmFsZW5jZQptb2RlbHNfcHJldiA8LSBsaXN0KG1vZGVsc19vX2NvdmlkLCAKICAgICAgICAgICAgICAgICAgICBtb2RlbHNfY19jb3ZpZCwgCiAgICAgICAgICAgICAgICAgICAgbW9kZWxzX2VfY292aWQsIAogICAgICAgICAgICAgICAgICAgIG1vZGVsc19hX2NvdmlkLCAKICAgICAgICAgICAgICAgICAgICBtb2RlbHNfbl9jb3ZpZCkKCnN1bV90YWJfcHJldiA8LSBzdW1tYXJ5X3RhYmxlKG1vZGVsc19wcmV2LCBkdl9uYW1lID0gJ3ByZXYnKQoKd3JpdGUudGFibGUoc3VtX3RhYl9wcmV2LCBxdW90ZT1GKQoKIyBzb2NpYWwgZGlzdGFuY2luZwptb2RlbHNfc29jZGlzdCA8LSBsaXN0KG1vZGVsc19vX3NvY2Rpc3QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19jX3NvY2Rpc3QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19lX3NvY2Rpc3QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19hX3NvY2Rpc3QsIAogICAgICAgICAgICAgICAgICAgICAgIG1vZGVsc19uX3NvY2Rpc3QpCgpzdW1fdGFiX3NvY2Rpc3QgPC0gc3VtbWFyeV90YWJsZShtb2RlbHNfc29jZGlzdCwgZHZfbmFtZSA9ICdzb2NkaXN0JywgcHJldj1UKQoKd3JpdGUudGFibGUoc3VtX3RhYl9zb2NkaXN0LCBxdW90ZT1GKQoKCgpgYGAKCiMgQ29uZGl0aW9uYWwgcmFuZG9tIGZvcmVzdCBhbmFseXNpcyAKCiMjIyBFeHRyYWN0IHNsb3BlcyBwcmV2YWxlbmNlCmBgYHtyfQoKIyBzbG9wZSBwcmV2YWxlbmNlCmRmX2dlcl9zbG9wZV9wcmV2IDwtIGRmX2dlciAlPiUgc3BsaXQoLiRrcmVpcykgJT4lIAogIG1hcCh+IGxtKHJhdGVfZGF5IH4gdGltZSwgZGF0YSA9IC4pKSAlPiUKICBtYXAoY29lZikgJT4lIAogIG1hcF9kYmwoJ3RpbWUnKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByb3duYW1lc190b19jb2x1bW4oJ2tyZWlzJykgJT4lIAogIHJlbmFtZShzbG9wZV9wcmV2ID0gJy4nKQoKIyBtZXJnZSB3aXRoIGNvbnRyb2wgdmFyaWFibGVzIApkZl9nZXJfc2xvcGVfcHJldiA8LSBkZl9nZXIgJT4lIHNlbGVjdCgtdGltZSwgLWRhdGUsIC1yYXRlX2RheSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JQogIGRpc3RpbmN0KCkgJT4lIAogIGlubmVyX2pvaW4oZGZfZ2VyX3Nsb3BlX3ByZXYsIGJ5ID0gJ2tyZWlzJykgJT4lCiAgZHJvcF9uYSgpCgpkZl9nZXJfc2xvcGVfcHJldgoKYGBgCgoKIyMjIEV4dHJhY3Qgc2xvcGVzIHNvY2lhbCBkaXN0YW5jaW5nCmBgYHtyfQoKIyBzbG9wZSBzb2NkaXN0CmRmX2dlcl9zbG9wZV9zb2NkaXN0IDwtIGRmX2dlcl9zY2FsZWQgJT4lIHNwbGl0KC4ka3JlaXMpICU+JQogIG1hcCh+IGxtKHNvY2Rpc3Rfc2luZ2xlX3RpbGUgfiB0aW1lLCBkYXRhID0gLikpICU+JQogIG1hcChjb2VmKSAlPiUKICBtYXBfZGJsKCd0aW1lJykgJT4lCiAgYXMuZGF0YS5mcmFtZSgpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigna3JlaXMnKSAlPiUKICByZW5hbWUoc2xvcGVfc29jZGlzdCA9ICcuJykKCgojIG1lcmdlIHdpdGggY29udHJvbCB2YXJpYWJsZXMgCmRmX2dlcl9zbG9wZV9zb2NkaXN0IDwtIGRmX2dlcl9zY2FsZWQgJT4lIAogIHNlbGVjdCgtdGltZSwgLWRhdGUsIC1zb2NkaXN0X3NpbmdsZV90aWxlLCAtcmF0ZV9kYXkpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgaW5uZXJfam9pbihkZl9nZXJfc2xvcGVfc29jZGlzdCwgYnkgPSAna3JlaXMnKSAlPiUKICBkcm9wX25hKCkKCmRmX2dlcl9zbG9wZV9zb2NkaXN0CgpgYGAKCiMjIyBFeHBsb3JlIGRpc3RyaWJ1dGlvbiBvZiBzbG9wZXMKYGBge3J9CgpkZl9nZXJfc2xvcGVfcHJldiAlPiUgZ2dwbG90KGFlcyhzbG9wZV9wcmV2KSkgKyBnZW9tX2hpc3RvZ3JhbShiaW5zID0gMTAwKQoKZGZfZ2VyX3Nsb3BlX3NvY2Rpc3QgJT4lIGdncGxvdChhZXMoc2xvcGVfc29jZGlzdCkpICsgZ2VvbV9oaXN0b2dyYW0oYmlucyA9IDEwMCkKCgpgYGAKCiMgQ1JGIHByZXZhbGVuY2UgfiBvcGVubmVzcwpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfb19maXRfcHJldiA8LSBjZm9yZXN0KHNsb3BlX3ByZXYgfiBwZXJzX28gKyB3b21lbiArIGFjYWRlbWljcyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zcGl0YWxfYmVkcyArIGdkcCArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0ICsgYWdlICsgcG9wZGVucywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl9nZXJfc2xvcGVfcHJldlstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9vX3ZhcmltcF9wcmV2IDwtIHZhcmltcChjcmZfb19maXRfcHJldiwgbnBlcm0gPSAxKQpjcmZfb192YXJpbXBfY29uZF9wcmV2IDwtIHZhcmltcChjcmZfb19maXRfcHJldiwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfb192YXJpbXBfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfb192YXJpbXBfY29uZF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgojIENSRiBwcmV2YWxlbmNlIH4gY29uc2NpZW50aW91c25lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2NfZml0X3ByZXYgPC0gY2ZvcmVzdChzbG9wZV9wcmV2IH4gcGVyc19jICsgd29tZW4gKyBhY2FkZW1pY3MgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3BpdGFsX2JlZHMgKyBnZHAgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydCArIGFnZSArIHBvcGRlbnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfZ2VyX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfY192YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2NfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2NfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2NfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gZXh0cmF2ZXJzaW9uCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9lX2ZpdF9wcmV2IDwtIGNmb3Jlc3Qoc2xvcGVfcHJldiB+IHBlcnNfZSArIHdvbWVuICsgYWNhZGVtaWNzICsKICAgICAgICAgICAgICAgICAgICAgICAgICBob3NwaXRhbF9iZWRzICsgZ2RwICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnQgKyBhZ2UgKyBwb3BkZW5zLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX2dlcl9zbG9wZV9wcmV2Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2VfdmFyaW1wX3ByZXYgPC0gdmFyaW1wKGNyZl9lX2ZpdF9wcmV2LCBucGVybSA9IDEpCmNyZl9lX3ZhcmltcF9jb25kX3ByZXYgPC0gdmFyaW1wKGNyZl9lX2ZpdF9wcmV2LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9lX3ZhcmltcF9wcmV2ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9lX3ZhcmltcF9jb25kX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgoKIyBDUkYgcHJldmFsZW5jZSB+IGFncmVlYWJsZW5lc3MKYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX2FfZml0X3ByZXYgPC0gY2ZvcmVzdChzbG9wZV9wcmV2IH4gcGVyc19hICsgd29tZW4gKyBhY2FkZW1pY3MgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3BpdGFsX2JlZHMgKyBnZHAgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydCArIGFnZSArIHBvcGRlbnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfZ2VyX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfYV92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX2FfZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX2FfdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX2FfZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX2FfdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX2FfdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBwcmV2YWxlbmNlIH4gbmV1cm90aWNpc20KYGBge3J9CgpjdHJscyA8LSBjZm9yZXN0X3VuYmlhc2VkKG50cmVlPTUwMCwgbXRyeT01KQoKY3JmX25fZml0X3ByZXYgPC0gY2ZvcmVzdChzbG9wZV9wcmV2IH4gcGVyc19uICsgd29tZW4gKyBhY2FkZW1pY3MgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGhvc3BpdGFsX2JlZHMgKyBnZHAgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydCArIGFnZSArIHBvcGRlbnMsIAogICAgICAgICAgICAgICAgICAgICAgICAgZGZfZ2VyX3Nsb3BlX3ByZXZbLTFdLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xzID0gY3RybHMpCgpjcmZfbl92YXJpbXBfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIG5wZXJtID0gMSkKY3JmX25fdmFyaW1wX2NvbmRfcHJldiA8LSB2YXJpbXAoY3JmX25fZml0X3ByZXYsIGNvbmRpdGlvbmFsID0gVCwgbnBlcm0gPSAxKQoKY3JmX25fdmFyaW1wX3ByZXYgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKY3JmX25fdmFyaW1wX2NvbmRfcHJldiAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpgYGAKCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IG9wZW5uZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9vX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfbyArIHdvbWVuICsgYWNhZGVtaWNzICsKICAgICAgICAgICAgICAgICAgICAgICAgICBob3NwaXRhbF9iZWRzICsgZ2RwICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnQgKyBhZ2UgKyBwb3BkZW5zLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX2dlcl9zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX29fdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9vX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9vX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9vX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9vX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9vX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IGNvbnNjaWVudGlvdXNuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9jX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfYyArIHdvbWVuICsgYWNhZGVtaWNzICsKICAgICAgICAgICAgICAgICAgICAgICAgICBob3NwaXRhbF9iZWRzICsgZ2RwICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnQgKyBhZ2UgKyBwb3BkZW5zLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX2dlcl9zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2NfdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9jX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9jX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9jX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9jX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9jX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgojIENSRiBzb2NpYWwgZGlzdGFuY2luZyB+IGV4dHJhdmVyc2lvbgpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfZV9maXRfc29jZGlzdCA8LSBjZm9yZXN0KHNsb3BlX3NvY2Rpc3QgfiBwZXJzX2UgKyB3b21lbiArIGFjYWRlbWljcyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zcGl0YWxfYmVkcyArIGdkcCArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0ICsgYWdlICsgcG9wZGVucywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl9nZXJfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9lX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfZV9maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfZV92YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfZV92YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBhZ3JlZWFibGVuZXNzCmBgYHtyfQoKY3RybHMgPC0gY2ZvcmVzdF91bmJpYXNlZChudHJlZT01MDAsIG10cnk9NSkKCmNyZl9hX2ZpdF9zb2NkaXN0IDwtIGNmb3Jlc3Qoc2xvcGVfc29jZGlzdCB+IHBlcnNfYSArIHdvbWVuICsgYWNhZGVtaWNzICsKICAgICAgICAgICAgICAgICAgICAgICAgICBob3NwaXRhbF9iZWRzICsgZ2RwICsgbWFudWZhY3QgKwogICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnQgKyBhZ2UgKyBwb3BkZW5zLCAKICAgICAgICAgICAgICAgICAgICAgICAgIGRmX2dlcl9zbG9wZV9zb2NkaXN0Wy0xXSwgCiAgICAgICAgICAgICAgICAgICAgICAgICBjb250cm9scyA9IGN0cmxzKQoKY3JmX2FfdmFyaW1wX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9hX2ZpdF9zb2NkaXN0LCBucGVybSA9IDEpCmNyZl9hX3ZhcmltcF9jb25kX3NvY2Rpc3QgPC0gdmFyaW1wKGNyZl9hX2ZpdF9zb2NkaXN0LCBjb25kaXRpb25hbCA9IFQsIG5wZXJtID0gMSkKCmNyZl9hX3ZhcmltcF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmNyZl9hX3ZhcmltcF9jb25kX3NvY2Rpc3QgJT4lIGFzLmRhdGEuZnJhbWUoKSAlPiUgcm93bmFtZXNfdG9fY29sdW1uKCd2YXJpYWJsZScpICU+JQogIGdncGxvdChhZXMoeD12YXJpYWJsZSwgeT0uKSkgKwogIGdlb21fYmFyKHN0YXQgPSAnaWRlbnRpdHknKSArIAogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKQoKYGBgCgoKIyBDUkYgc29jaWFsIGRpc3RhbmNpbmcgfiBuZXVyb3RpY2lzbQpgYGB7cn0KCmN0cmxzIDwtIGNmb3Jlc3RfdW5iaWFzZWQobnRyZWU9NTAwLCBtdHJ5PTUpCgpjcmZfbl9maXRfc29jZGlzdCA8LSBjZm9yZXN0KHNsb3BlX3NvY2Rpc3QgfiBwZXJzX24gKyB3b21lbiArIGFjYWRlbWljcyArCiAgICAgICAgICAgICAgICAgICAgICAgICAgaG9zcGl0YWxfYmVkcyArIGdkcCArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICBhaXJwb3J0ICsgYWdlICsgcG9wZGVucywgCiAgICAgICAgICAgICAgICAgICAgICAgICBkZl9nZXJfc2xvcGVfc29jZGlzdFstMV0sIAogICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbHMgPSBjdHJscykKCmNyZl9uX3ZhcmltcF9zb2NkaXN0IDwtIHZhcmltcChjcmZfbl9maXRfc29jZGlzdCwgbnBlcm0gPSAxKQpjcmZfbl92YXJpbXBfY29uZF9zb2NkaXN0IDwtIHZhcmltcChjcmZfbl9maXRfc29jZGlzdCwgY29uZGl0aW9uYWwgPSBULCBucGVybSA9IDEpCgpjcmZfbl92YXJpbXBfc29jZGlzdCAlPiUgYXMuZGF0YS5mcmFtZSgpICU+JSByb3duYW1lc190b19jb2x1bW4oJ3ZhcmlhYmxlJykgJT4lCiAgZ2dwbG90KGFlcyh4PXZhcmlhYmxlLCB5PS4pKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICdpZGVudGl0eScpICsgCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCkpCgpjcmZfbl92YXJpbXBfY29uZF9zb2NkaXN0ICU+JSBhcy5kYXRhLmZyYW1lKCkgJT4lIHJvd25hbWVzX3RvX2NvbHVtbigndmFyaWFibGUnKSAlPiUKICBnZ3Bsb3QoYWVzKHg9dmFyaWFibGUsIHk9LikpICsKICBnZW9tX2JhcihzdGF0ID0gJ2lkZW50aXR5JykgKyAKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkKCmBgYAoKIyBDaGFuZ2UgcG9pbnQgYW5hbHlzaXMKIyMjIFByZXBhcmF0aW9uCmBgYHtyfQoKIyBrZWVwIG9ubHkgY291bnRpZXMgd2l0aCBmdWxsIGRhdGEKa3JlaXNfY29tcGxldGUgPC0gZGZfZ2VyX3NjYWxlZCAlPiUgCiAgZ3JvdXBfYnkoa3JlaXMpICU+JSAKICBzdW1tYXJpemUobiA9IG4oKSkgJT4lIAogIGZpbHRlcihuPT1tYXgoLiRuKSkgJT4lIAogIC4ka3JlaXMKYGBgCgojIyMgUHJldmFsZW5jZQpgYGB7cn0KCiMgcnVuIGNoYW5nZXBvaW50IGFuYWx5c2lzCmRmX2dlcl9wcmV2X2NwdF9yZXN1bHRzIDwtIGRmX2dlcl9zY2FsZWQgJT4lIHNlbGVjdChrcmVpcywgcmF0ZV9kYXkpICU+JQogIGZpbHRlcihrcmVpcyAlaW4lIGtyZWlzX2NvbXBsZXRlKSAlPiUgCiAgc3BsaXQoLiRrcmVpcykgJT4lCiAgbWFwKH4gY3B0Lm1lYW52YXIoYXMudmVjdG9yKC4kcmF0ZV9kYXkpLAogICAgICAgICAgICAgICAgICAgIGNsYXNzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgcGFyYW0uZXN0aW1hdGVzPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgUT0xKSkKCiMgY2FsY3VsYXRlIGNoYW5nZSBwb2ludHMKZGZfZ2VyX3ByZXZfY3B0X2RheSA8LSBkZl9nZXJfcHJldl9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKGNwdHMpICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUoY3B0X2RheV9wcmV2ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2tyZWlzJykKCiMgY2FsY3VsYXRlIG1lYW4gZGlmZmVyZW5jZXMKZGZfZ2VyX3ByZXZfY3B0X21lYW5fZGlmZiA8LSBkZl9nZXJfcHJldl9jcHRfcmVzdWx0cyAlPiUgCiAgbWFwKHBhcmFtLmVzdCkgJT4lIAogIG1hcCh+IC4kbWVhbikgJT4lIAogIG1hcCh+IC5bMl0tLlsxXSkgJT4lIAogIHVubGlzdCgpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHJlbmFtZShtZWFuX2RpZmZfcHJldiA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdrcmVpcycpCgojIGNhbGN1bGF0ZSB2YXJhaW5jZSBkaWZmZXJlbmNlcwpkZl9nZXJfcHJldl9jcHRfdmFyX2RpZmYgPC0gZGZfZ2VyX3ByZXZfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJHZhcmlhbmNlKSAlPiUgCiAgbWFwKH4gLlsyXS0uWzFdKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKHZhcl9kaWZmX3ByZXYgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigna3JlaXMnKQoKIyBtZXJnZSBuZXcgdmFyaWFibGVzIApkZl9nZXJfY3B0X3ByZXYgPC0gZGZfZ2VyX3NjYWxlZCAlPiUKICBzZWxlY3QoLXRpbWUsIC1yYXRlX2RheSwgLXNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JQogIGRpc3RpbmN0KCkgJT4lCiAgbXV0YXRlKGtyZWlzID0gYXMuY2hhcmFjdGVyKGtyZWlzKSkgJT4lCiAgbGVmdF9qb2luKGRmX2dlcl9wcmV2X2NwdF9kYXksIGJ5PSdrcmVpcycpICU+JQogIGxlZnRfam9pbihkZl9nZXJfcHJldl9jcHRfbWVhbl9kaWZmLCBieT0na3JlaXMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfZ2VyX3ByZXZfY3B0X3Zhcl9kaWZmLCBieT0na3JlaXMnKQoKZGZfZ2VyX2NwdF9wcmV2ICU+JSBzZWxlY3QoY3B0X2RheV9wcmV2KSAlPiUgbWFwKGhpc3QpCmRmX2dlcl9jcHRfcHJldiAlPiUgc2VsZWN0KG1lYW5fZGlmZl9wcmV2KSAlPiUgbWFwKGhpc3QpCmRmX2dlcl9jcHRfcHJldiAlPiUgc2VsZWN0KHZhcl9kaWZmX3ByZXYpICU+JSBtYXAoaGlzdCkKCmRmX2dlcl9jcHRfcHJldiAlPiUgZGltKCkKZGZfZ2VyX2NwdF9wcmV2ICU+JSBkcm9wX25hKCkgJT4lIGRpbSgpCgpgYGAKCgpgYGB7cn0KCmZvcihpIGluIGhlYWQoZGZfZ2VyX3ByZXZfY3B0X3Jlc3VsdHMsNSkpewogIHBsb3QoaSkKfQoKYGBgCgojIyMgU29jaWFsIGRpc3RhbmNpbmcKYGBge3J9CgojIHJ1biBjaGFuZ2Vwb2ludCBhbmFseXNpcwpkZl9nZXJfc29jZGlzdF9jcHRfcmVzdWx0cyA8LSBkZl9nZXJfc2NhbGVkICU+JSBzZWxlY3Qoa3JlaXMsIHNvY2Rpc3Rfc2luZ2xlX3RpbGUpICU+JQogIGZpbHRlcihrcmVpcyAlaW4lIGtyZWlzX2NvbXBsZXRlKSAlPiUgCiAgc3BsaXQoLiRrcmVpcykgJT4lCiAgbWFwKH4gY3B0Lm1lYW52YXIoYXMudmVjdG9yKC4kc29jZGlzdF9zaW5nbGVfdGlsZSksCiAgICAgICAgICAgICAgICAgICAgI3BlbmFsdHkgPSAnQXN5bXB0b3RpYycsCiAgICAgICAgICAgICAgICAgICAgY2xhc3M9VFJVRSwKICAgICAgICAgICAgICAgICAgICBwYXJhbS5lc3RpbWF0ZXM9VFJVRSwKICAgICAgICAgICAgICAgICAgICBRPTEsCiAgICAgICAgICAgICAgICAgICAgdGVzdC5zdGF0ID0gJ05vcm1hbCcpKQoKIyBjYWxjdWxhdGUgY2hhbmdlIHBvaW50CmRmX2dlcl9zb2NkaXN0X2NwdF9kYXkgPC0gZGZfZ2VyX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChjcHRzKSAlPiUgCiAgdW5saXN0KCkgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgcmVuYW1lKGNwdF9kYXlfc29jZGlzdCA9ICcuJykgJT4lCiAgcm93bmFtZXNfdG9fY29sdW1uKCdrcmVpcycpCgojIGNhbGN1bGF0ZSBtZWFuIGRpZmZlcmVuY2VzCmRmX2dlcl9zb2NkaXN0X2NwdF9tZWFuX2RpZmYgPC0gZGZfZ2VyX3NvY2Rpc3RfY3B0X3Jlc3VsdHMgJT4lIAogIG1hcChwYXJhbS5lc3QpICU+JSAKICBtYXAofiAuJG1lYW4pICU+JSAKICBtYXAofiAuWzJdLS5bMV0pICU+JSAKICB1bmxpc3QoKSAlPiUgCiAgYXMuZGF0YS5mcmFtZSgpICU+JSAKICByZW5hbWUobWVhbl9kaWZmX3NvY2Rpc3QgPSAnLicpICU+JQogIHJvd25hbWVzX3RvX2NvbHVtbigna3JlaXMnKQoKIyBjYWxjdWxhdGUgdmFyYWluY2UgZGlmZmVyZW5jZXMKZGZfZ2VyX3NvY2Rpc3RfY3B0X3Zhcl9kaWZmIDwtIGRmX2dlcl9zb2NkaXN0X2NwdF9yZXN1bHRzICU+JSAKICBtYXAocGFyYW0uZXN0KSAlPiUgCiAgbWFwKH4gLiR2YXJpYW5jZSkgJT4lIAogIG1hcCh+IC5bMl0tLlsxXSkgJT4lIAogIHVubGlzdCgpICU+JSAKICBhcy5kYXRhLmZyYW1lKCkgJT4lIAogIHJlbmFtZSh2YXJfZGlmZl9zb2NkaXN0ID0gJy4nKSAlPiUKICByb3duYW1lc190b19jb2x1bW4oJ2tyZWlzJykKCiMgbWVyZ2UgbmV3IHZhcmlhYmxlcyAKZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QgPC0gZGZfZ2VyX2NwdF9wcmV2ICU+JQogIGxlZnRfam9pbihkZl9nZXJfc29jZGlzdF9jcHRfZGF5LCBieT0na3JlaXMnKSAlPiUKICBsZWZ0X2pvaW4oZGZfZ2VyX3NvY2Rpc3RfY3B0X21lYW5fZGlmZiwgYnk9J2tyZWlzJykgJT4lCiAgbGVmdF9qb2luKGRmX2dlcl9zb2NkaXN0X2NwdF92YXJfZGlmZiwgYnk9J2tyZWlzJykKCmRmX2dlcl9jcHRfcHJldl9zb2NkaXN0ICU+JSBzZWxlY3QoY3B0X2RheV9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCmRmX2dlcl9jcHRfcHJldl9zb2NkaXN0ICU+JSBzZWxlY3QobWVhbl9kaWZmX3NvY2Rpc3QpICU+JSBtYXAoaGlzdCkKZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIHNlbGVjdCh2YXJfZGlmZl9zb2NkaXN0KSAlPiUgbWFwKGhpc3QpCgpkZl9nZXJfY3B0X3ByZXZfc29jZGlzdCAlPiUgZGltKCkKZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QgJT4lIGRyb3BfbmEoKSAlPiUgZGltKCkKCmBgYAoKYGBge3J9Cgpmb3IoaSBpbiBoZWFkKGRmX2dlcl9zb2NkaXN0X2NwdF9yZXN1bHRzLDUpKXsKICBwbG90KGkpCn0KCmBgYAoKIyBQcmVkaWN0aW5nIGNoYW5nZSBwb2ludHMgCiMjIyBMaW5lYXIgbW9kZWxzIHByZWRpY3RpbmcgY2hhbmdlIHBvaW50cyAobm8gY29udHJvbHMpCmBgYHtyfQoKbG1fY3ByX3ByZXZfcGVycyA8LSBsbShjcHRfZGF5X3ByZXYgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24sIAogICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9jcHRfcHJldl9zb2NkaXN0KQpsbV9jcHJfcHJldl9wZXJzICU+JSBzdW1tYXJ5KCkKCgpsbV9jcHRfc29jZGlzdF9wZXJzIDwtIGxtKGNwdF9kYXlfc29jZGlzdCB+IHBlcnNfbyArIHBlcnNfYyArIHBlcnNfZSArIHBlcnNfYSArIHBlcnNfbiwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9zb2NkaXN0X3BlcnMgJT4lIHN1bW1hcnkoKQoKYGBgCgojIyMgTGluZWFyIG1vZGVscyBwcmVkaWN0aW5nIGNoYW5nZSBwb2ludHMgd2l0aCBjb250cm9scwpgYGB7cn0KZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QKCmxtX2NwdF9wcmV2X3BlcnMgPC0gbG0oY3B0X2RheV9wcmV2IH4gcGVyc19vICsgcGVyc19jICsgcGVyc19lICsgcGVyc19hICsgcGVyc19uICsgCiAgICAgICAgICAgICAgICAgICAgICAgICB3b21lbiArIGFjYWRlbWljcyArIGhvc3BpdGFsX2JlZHMgKyBnZHAgKyBtYW51ZmFjdCArCiAgICAgICAgICAgICAgICAgICAgICAgICAgYWlycG9ydCArIGFnZSArIHBvcGRlbnMsCiAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gZGZfZ2VyX2NwdF9wcmV2X3NvY2Rpc3QpCmxtX2NwdF9wcmV2X3BlcnMgJT4lIHN1bW1hcnkoKQoKbG1fY3B0X3NvY2Rpc3RfcGVycyA8LSBsbShjcHRfZGF5X3NvY2Rpc3QgfiBwZXJzX28gKyBwZXJzX2MgKyBwZXJzX2UgKyBwZXJzX2EgKyBwZXJzX24gKyAKICAgICAgICAgICAgICAgICAgICAgICAgICAgIHdvbWVuICsgYWNhZGVtaWNzICsgaG9zcGl0YWxfYmVkcyArIGdkcCArIG1hbnVmYWN0ICsKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFpcnBvcnQgKyBhZ2UgKyBwb3BkZW5zLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGF0YSA9IGRmX2dlcl9jcHRfcHJldl9zb2NkaXN0KQpsbV9jcHRfc29jZGlzdF9wZXJzICU+JSBzdW1tYXJ5KCkKCmBgYAoKCg==